﻿#include "tcpsocketnetworkcenter.h"

#include <QUuid>
#include <qglobalconfig.h>
#include "devicemonitorheader.h"

QMutex TcpSocketNetWorkCenter::mutex;
TcpSocketNetWorkCenter* TcpSocketNetWorkCenter::instance = nullptr;

TcpSocketNetWorkCenter *TcpSocketNetWorkCenter::getInstance()
{
    if (instance == nullptr) {
        QMutexLocker locker(&mutex);
        if (instance == nullptr) {
            instance = new TcpSocketNetWorkCenter();
        }
    }
    return instance;
}

void TcpSocketNetWorkCenter::deleteInstance()
{
    if (instance != nullptr) {
        delete instance;
        instance = nullptr;
    }
}

void TcpSocketNetWorkCenter::sendMessage(QString &message)
{
    signal_send_message(message);
}

TcpSocketNetWorkCenter::TcpSocketNetWorkCenter(QObject *parent) : QThread(parent)
{
    qDebug() << __FUNCTION__;
    moveToThread(this); // 确保对象在自己的线程中运行
    sendPackId = 0;
    connect(this,&TcpSocketNetWorkCenter::signal_send_message,this,&TcpSocketNetWorkCenter::slot_send_message,Qt::BlockingQueuedConnection);
    start();
}

TcpSocketNetWorkCenter::~TcpSocketNetWorkCenter()
{
    quit();
    wait();
    qDebug() << __FUNCTION__;
}

quint16 TcpSocketNetWorkCenter::getSendPackId()
{
    quint16 nowId = sendPackId;
    sendPackId++;
    return nowId;
}

void TcpSocketNetWorkCenter::slot_send_message(QString &message)
{
    QByteArray byteArray = message.toLatin1();
    QByteArray sendByteArray;
    sendByteArray.resize(TCP_SOCKET_FRAME_LEN);
    int sendDataLen = TCP_SOCKET_FRAME_LEN - sizeof(SocketFrameHeader);
    SocketFrameHeader socketFrameHeader;
    socketFrameHeader.packId = getSendPackId();
    socketFrameHeader.packLen = byteArray.size();
    socketFrameHeader.frameSerial = 0;//帧序号

    while(byteArray.size() > 0){
        socketFrameHeader.dataLen = byteArray.size() > sendDataLen ? sendDataLen : byteArray.size();
        if(byteArray.size() <= sendDataLen){
            socketFrameHeader.frameMark = FRAME_MARK_END;
        }else{
            socketFrameHeader.frameMark = FRAME_MARK_CENTER;
        }
        memcpy(sendByteArray.data(),&socketFrameHeader,sizeof(SocketFrameHeader));
        memcpy(sendByteArray.data() + sizeof(SocketFrameHeader),byteArray.data(),byteArray.size() > sendDataLen ? sendDataLen : byteArray.size());

        clientMapMutex.lock();
        for(auto *socket : clientMap){
            if(socket->bytesToWrite() < 65536){
                socket->write(sendByteArray);
            }
        }
        clientMapMutex.unlock();

        byteArray.remove(0,byteArray.size() > sendDataLen ? sendDataLen : byteArray.size());
        socketFrameHeader.frameSerial++;
        QThread::msleep(1);
    }

}

void TcpSocketNetWorkCenter::handleNewConnection()
{
    QMutexLocker locket(&clientMapMutex);
    QTcpSocket *pClient = m_server->nextPendingConnection();
    QString key = QUuid::createUuid().toString(); // 使用UUID作为每个连接的唯一标识符
    pClient->setProperty("connectKey",key);
    clientMap.insert(key, pClient);
    qDebug() << __FUNCTION__ << "TcpSocket Connection insert:" << pClient->property("connectKey").toString();
//    connect(pClient, &QWebSocket::textMessageReceived, this, &SpectrumSituationWebSocketServer::processTextMessage);
    connect(pClient, &QTcpSocket::disconnected, this, &TcpSocketNetWorkCenter::onSocketDisconnected);
}

void TcpSocketNetWorkCenter::onSocketDisconnected()
{
    QMutexLocker locker(&clientMapMutex);
    QTcpSocket *pClient = qobject_cast<QTcpSocket *>(sender());
    if (pClient) {
        clientMap.remove(pClient->property("connectKey").toString());
        qDebug()<< __FUNCTION__ << "TcpSocket Connection removed:" << pClient->property("connectKey").toString();
        pClient->deleteLater();// 安全地删除客户端对象
    }
}

void TcpSocketNetWorkCenter::run()
{
    QString listenAdderss = QGlobalConfig::getInstance().read("tcpsocket","listenAdderss","127.0.0.1").toString();
    quint16 listenPort = QGlobalConfig::getInstance().read("tcpsocket","listenPort",3812).toUInt();
    m_server = new QTcpServer(this);
    if (m_server->listen(QHostAddress::AnyIPv4, listenPort)) {
        QHostAddress serverAddress = m_server->serverAddress();
        qDebug() << __FUNCTION__  << QString("TcpSocket server listening on address:%1 port:%2").arg(serverAddress.toString()).arg(listenPort) << "in thread" << QThread::currentThreadId();
        connect(m_server, &QTcpServer::newConnection, this, &TcpSocketNetWorkCenter::handleNewConnection);
    } else {
        qDebug() << "Failed to start TcpSocket server";
    }
    exec(); // 进入事件循环，等待处理新连接
    m_server->close();
    delete m_server;
}
